package nicg.st.service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Set;
import java.util.Stack;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import nicg.st.dao.IndicatorSystemMapper;
import nicg.st.entity.AddIndicatorVO;
import nicg.st.entity.AddTreeVO;
import nicg.st.entity.BuildTreeVO;
import nicg.st.entity.CalMethodPO;
import nicg.st.entity.EditVO;
import nicg.st.entity.EvalMethodPO;
import nicg.st.entity.EvalParamPO;
import nicg.st.entity.ExpertScorePO;
import nicg.st.entity.ExpertVO;
import nicg.st.entity.IndicatorBase2PO;
import nicg.st.entity.IndicatorBasePO;
import nicg.st.entity.IndicatorBaseVO;
import nicg.st.entity.IndicatorDetailPO;
import nicg.st.entity.InputParamInfo;
import nicg.st.entity.JSFFPO;
import nicg.st.entity.ListEntity;
import nicg.st.entity.MatrixBuildVO;
import nicg.st.entity.MyConfig;
import nicg.st.entity.ParamCalPO;
import nicg.st.entity.ParamInfoPO;
import nicg.st.entity.ParamPrototype;
import nicg.st.entity.PieNeedVO;
import nicg.st.entity.PieVO;
import nicg.st.entity.PresetParamInfo;
import nicg.st.entity.SaveEditVO;
import nicg.st.entity.SliderVO;
import nicg.st.entity.StepVO;
import nicg.st.entity.TreeMindVO;
import nicg.st.entity.TreeVO;
import nicg.st.exception.DbException;
import nicg.st.exception.GlobalException;
import nicg.st.service.ahp.AHP;
import nicg.st.util.DecodeMatrix;
import nicg.st.util.DecodePath;
import nicg.st.util.EncodeMatrix;
import nicg.st.util.EncodePath;
import nicg.st.util.ErrorCode;
import nicg.st.util.Log;
import nicg.st.util.ResponseUtil;

/**
 * @author GeChen
 * @Description
 * @date 2019/11/3 23:18
 */
@Service
public class IndicatorSystemService {
	@Autowired
	IndicatorSystemMapper indicatorSystemMapper;
	@Resource
	MyConfig myConfig;
	@Autowired
	UserService userService;

	// 得到所有的指标体系信息
	public String getAllIndicatorSystem() {
		Log.printLog(this.getClass().getName(), Thread.currentThread().getStackTrace()[1].getMethodName());
		String userId = userService.getCurUserId();
		if (userId == null) {
			throw new GlobalException("未获取到当前用户信息，请联系管理员");
		}
		List<IndicatorBasePO> indicatorBasePOS = indicatorSystemMapper.getAllIndicatorBasePO(userId);
		if (indicatorBasePOS.size() <= 0) {
			return ResponseUtil.getResponseString(ErrorCode.ERROR, "未查询到相关指标体系，请联系系统管理员", "");
		} else {
			List<IndicatorBaseVO> indicatorBaseVOS = getIndicatorBaseVOByPO(indicatorBasePOS);
			return ResponseUtil.getResponseString(ErrorCode.SUCCESSFUL, "查询成功", indicatorBaseVOS);
		}
	}

	// 得到指标体系的数目
	public String getIndicatorSystemCount() {
		Log.printLog(this.getClass().getName(), Thread.currentThread().getStackTrace()[1].getMethodName());
		String userId = userService.getCurUserId();
		if (userId == null) {
			throw new GlobalException("未获取到当前用户信息，请联系管理员");
		}
		Integer count = indicatorSystemMapper.getIndicatorSystemCount(userId);
		if (count == null)
			return ResponseUtil.getResponseString(ErrorCode.ERROR, "查询指标体系数目错误，请联系系统管理员", "");
		else
			return ResponseUtil.getResponseString(ErrorCode.SUCCESSFUL, "查询成功", count);
	}

	/**
	 * 返回指定页数的指标体系
	 * 
	 * @param page
	 * @return
	 */
	public String getIndicatorSystemByPage(int page) {
		Log.printLog(this.getClass().getName(), Thread.currentThread().getStackTrace()[1].getMethodName());
		String userId = userService.getCurUserId();
		if (userId == null) {
			throw new GlobalException("未获取到当前用户信息，请联系管理员");
		}
		int pageLimit = Integer.parseInt(myConfig.getPageLimit());
		List<IndicatorBasePO> indicatorBasePOS = indicatorSystemMapper.getIndicatorSystemByPage((page - 1) * pageLimit,
				userId, pageLimit);
		if (indicatorBasePOS == null)
			throw new GlobalException("查询第" + page + "页的指标体系错误，请联系系统管理员！");
		else {
			List<IndicatorBaseVO> indicatorBaseVOS = getIndicatorBaseVOByPO(indicatorBasePOS);
			return ResponseUtil.getResponseString(ErrorCode.SUCCESSFUL, "查询成功", indicatorBaseVOS);
		}
	}

	/**
	 * 根据指标体系的id查询指标体系的名称
	 * 
	 * @param indicatorId
	 * @return
	 */
	public String getRootIndicatorDetailByIndicatorId(int indicatorId) {
		Log.printLog(this.getClass().getName(), Thread.currentThread().getStackTrace()[1].getMethodName());
		String indicatorName = indicatorSystemMapper.getIndicatorBaseNameByIndicatorId(indicatorId);
		if (indicatorName == null)
			throw new GlobalException("查询根指标节点错误。");
		else
			return ResponseUtil.getResponseString(ErrorCode.SUCCESSFUL, "查询成功", indicatorName);
	}

	// 根据指标体系的id查询该指标体系的信息
	public String getRootIndicatorDetailPOByIndicatorId(int indicatorId) {
		Log.printLog(this.getClass().getName(), Thread.currentThread().getStackTrace()[1].getMethodName());
		IndicatorDetailPO indicatorDetailPO = indicatorSystemMapper.getRootIndicatorDetailByIndicatorId(indicatorId);
		if (indicatorDetailPO == null)
			return ResponseUtil.getResponseString(ErrorCode.ERROR, "查询指标体系根节点错误，请联系系统管理员", "");
		else
			return ResponseUtil.getResponseString(ErrorCode.SUCCESSFUL, "查询成功", indicatorDetailPO);
	}

	// 根据指标体系的id返回树形VO不带权重字符
	public String getTreeVOByIndicatorId(int indicatorId) {
		Log.printLog(this.getClass().getName(), Thread.currentThread().getStackTrace()[1].getMethodName());
		List<IndicatorDetailPO> indicatorDetailPOS = indicatorSystemMapper
				.getOrderdIndicatorDetailByIndicatorId(indicatorId);
		if (indicatorDetailPOS == null)
			return ResponseUtil.getResponseString(ErrorCode.ERROR, "查询指标体系错误，请联系系统管理员", "");
		else {
			List<TreeVO> treeVOS = getTreeList(indicatorDetailPOS, indicatorId);
			return ResponseUtil.getResponseString(ErrorCode.SUCCESSFUL, "查询成功", treeVOS);
		}
	}

	// 根据指标体系的id返回树形VO带权重字符
	public String getTreeVOByIndicatorIdNeedContat(int indicatorId) {
		Log.printLog(this.getClass().getName(), Thread.currentThread().getStackTrace()[1].getMethodName());
		List<IndicatorDetailPO> indicatorDetailPOS = indicatorSystemMapper
				.getOrderdIndicatorDetailByIndicatorId(indicatorId);
		if (indicatorDetailPOS == null)
			return ResponseUtil.getResponseString(ErrorCode.ERROR, "查询指标体系错误，请联系系统管理员", "");
		else {
			List<TreeVO> treeVOS = getTreeList(indicatorDetailPOS, indicatorId);
			getContat(treeVOS.get(0));
			return ResponseUtil.getResponseString(ErrorCode.SUCCESSFUL, "查询成功", treeVOS);
		}
	}

	private void getContat(TreeVO treeVO) {
		if (treeVO == null)
			return;
		treeVO.setIndicatorName(treeVO.getIndicatorName() + "        " + treeVO.getRelativeWeight());
		if (treeVO.getChildList() == null)
			return;
		for (TreeVO treeVO1 : treeVO.getChildList()) {
			getContat(treeVO1);
		}
	}

	// 根据指标体系的id返回树形思维导图VO
	public String getTreeMindVOByIndicatorId(int indicatorId) {
		Log.printLog(this.getClass().getName(), Thread.currentThread().getStackTrace()[1].getMethodName());
		List<IndicatorDetailPO> indicatorDetailPOS = indicatorSystemMapper
				.getOrderdIndicatorDetailByIndicatorId(indicatorId);
		if (indicatorDetailPOS == null)
			return ResponseUtil.getResponseString(ErrorCode.ERROR, "查询指标体系错误，请联系系统管理员", "");
		else {
			List<TreeMindVO> treeVOS = getTreeMindList(indicatorDetailPOS, indicatorId);

			return ResponseUtil.getResponseString(ErrorCode.SUCCESSFUL, "查询成功", treeVOS);
		}
	}

	// 根据指标体系的id返回详细信息
	public String getIndicatorInfoById(int indicatorId) {
		Log.printLog(this.getClass().getName(), Thread.currentThread().getStackTrace()[1].getMethodName());
		List<IndicatorDetailPO> indicatorDetailPOS = indicatorSystemMapper
				.getDoubleOrderdIndicatorDetailByIndicatorId(indicatorId);
		if (indicatorDetailPOS == null)
			return ResponseUtil.getResponseString(ErrorCode.ERROR, "查询指标体系错误，请联系系统管理员", "");
		else
			return ResponseUtil.getResponseString(ErrorCode.SUCCESSFUL, "查询成功", indicatorDetailPOS);
	}

	// 根据指标体系的List返回TreeVO
	public List<TreeVO> getTreeList(List<IndicatorDetailPO> entityList, int indicatorId) {
		List<IndicatorDetailPO> newEntityList = entityList;
		List<TreeVO> oldTree = new ArrayList<>();
		try {
			oldTree = getTreeVOListWithoutParentByDetailList(newEntityList);
		} catch (Exception e) {
			throw new GlobalException("错误");
		}
		while (oldTree.size() > 1) {
			TreeVO treeVO = oldTree.get(oldTree.size() - 1);
			Stack<TreeVO> stack = new Stack<>();
			stack.push(treeVO);
			oldTree.remove(oldTree.size() - 1);
			for (int i = 0; i < oldTree.size(); i++) {
				if (oldTree.get(i).getParentId().equals(treeVO.getParentId())) {
					stack.push(oldTree.get(i));
					oldTree.remove(i);
					i--;
				}
			}
			List<TreeVO> treeVOS = new ArrayList<>();
			TreeVO treeVOtop = stack.peek();
			int parentId = treeVOtop.getParentId();
			int index = 0;
			for (int i = 0; i < oldTree.size(); i++) {
				if (oldTree.get(i).getId().equals(parentId)) {
					index = i;
				}
			}
			while (stack.size() > 0) {
				TreeVO treeVO1 = stack.pop();
				treeVOS.add(treeVO1);
			}
			oldTree.get(index).setChildList(treeVOS);
		}
		return oldTree;
	}

	// 根据指标体系的List返回TreeMindVO
	public List<TreeMindVO> getTreeMindList(List<IndicatorDetailPO> oldEntityList, int indicatorId) {
		List<IndicatorDetailPO> entityList = oldEntityList;
		List<TreeMindVO> oldTree = new ArrayList<>();
		// 设置TreeMindVO的绝对权重，相对权重和体系名称
		for (int i = 0; i < entityList.size(); i++) {
			TreeMindVO treeVO = new TreeMindVO();
			treeVO.setName(entityList.get(i).getIndicatorName());
			treeVO.setValue(entityList.get(i).getRelativeWeight());
			treeVO.setId(entityList.get(i).getId());
			String path = entityList.get(i).getIndicatorPath();
			List<String> paths = DecodePath.decodePath(path);
			if (i != 0) {
				int index = 0;
				for (int g = 0; g < paths.size(); g++) {
					if (paths.get(g).equals(entityList.get(i).getIndicatorName())) {
						index = g - 1;
					}
				}
				IndicatorDetailPO parent = indicatorSystemMapper.getIndicatorDetailByIndicatorName(paths.get(index),
						indicatorId);
				treeVO.setParentId(parent.getId());
			} else
				treeVO.setParentId(-1);
			oldTree.add(treeVO);
		}
		while (oldTree.size() > 1) {
			TreeMindVO treeVO = oldTree.get(oldTree.size() - 1);
			Stack<TreeMindVO> stack = new Stack<>();
			stack.push(treeVO);
			oldTree.remove(oldTree.size() - 1);
			for (int i = 0; i < oldTree.size(); i++) {
				if (oldTree.get(i).getParentId().equals(treeVO.getParentId())) {
					stack.push(oldTree.get(i));
					oldTree.remove(i);
					i--;
				}
			}
			List<TreeMindVO> treeVOS = new ArrayList<>();
			TreeMindVO treeVOtop = stack.peek();
			int parentId = treeVOtop.getParentId();
			int index = 0;
			for (int i = 0; i < oldTree.size(); i++) {
				if (oldTree.get(i).getId().equals(parentId)) {
					index = i;
				}
			}
			while (stack.size() > 0) {
				TreeMindVO treeVO1 = stack.pop();
				treeVOS.add(treeVO1);
			}
			oldTree.get(index).setChildren(treeVOS);
		}
		return oldTree;
	}

	// 通过IndicatorBasePO构造IndicatorBaseVO
	public List<IndicatorBaseVO> getIndicatorBaseVOByPO(List<IndicatorBasePO> indicatorBasePOS) {
		List<IndicatorBaseVO> indicatorBaseVOS = new ArrayList<>();
		for (IndicatorBasePO indicatorBasePO : indicatorBasePOS) {
			String userId = userService.getCurUserId();
			if (userId == null) {
				throw new GlobalException("未获取到当前用户信息，请联系管理员");
			}
			IndicatorBaseVO indicatorBaseVO = new IndicatorBaseVO();
			indicatorBaseVO.setIndicatorBasePO(indicatorBasePO);
			indicatorBaseVO.setUserName("user" + userId);
			indicatorBaseVOS.add(indicatorBaseVO);
		}
		return indicatorBaseVOS;
	}

	/**
	 * 通过指标体系的名称查询对应的指标体系
	 * 
	 * @param name
	 * @return
	 */
	public String getIndicatorInfoByName(String name) {
		Log.printLog(this.getClass().getName(), Thread.currentThread().getStackTrace()[1].getMethodName());
		IndicatorBasePO indicatorBasePO = indicatorSystemMapper.getIndicatorInfoByName(name);
		if (indicatorBasePO != null) {
			throw new GlobalException("存在指标体系！");
		} else
			return ResponseUtil.getResponseString(ErrorCode.SUCCESSFUL, "暂无相关指标体系", "");
	}

	public double get45De4(double sum) {
		BigDecimal b = new BigDecimal(sum);
		return b.setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();
	}

	/**
	 * 根据选择的树形结构及用户信息新增指标体系
	 * 
	 * @param buildTreeVO
	 * @return
	 */
	public String insertIndicatorByTreeVO(BuildTreeVO buildTreeVO) {
		Log.printLog(this.getClass().getName(), Thread.currentThread().getStackTrace()[1].getMethodName());
		String indicatorName = buildTreeVO.getName();
		Date createTime = new Date();
		String userId = userService.getCurUserId();
		if (userId == null) {
			throw new GlobalException("未获取到当前用户信息，请联系管理员");
		}
		int prIndicatorSystemId = buildTreeVO.getIndicatorSystemId();
		List<ListEntity> list = buildTreeVO.getList();
		// 写到指标体系基本信息表中
		IndicatorBasePO indicatorBasePO = indicatorSystemMapper.getIndicatorInfoByName(indicatorName);
		if (indicatorBasePO != null) {
			throw new GlobalException("写入基本信息表错误，请联系系统管理员");
		}
		String name = indicatorSystemMapper.getIndicatorBaseNameByIndicatorId(prIndicatorSystemId);
		if (name == null) {
			throw new GlobalException("获取模板指标体系错误。");
		}
		IndicatorBasePO oldBasePO = indicatorSystemMapper.getIndicatorInfoByName(name);
		if (oldBasePO == null) {
			throw new GlobalException("获取模板指标体系错误。");
		}
		try {
			indicatorSystemMapper.insertIndicatorBasePO(oldBasePO.getTaskName(), userId, createTime, null, "用户自定义",
					oldBasePO.getParentId(), oldBasePO.getUserLevel(), oldBasePO.getTaskType(), indicatorName);
		} catch (Exception e) {
			throw new GlobalException("插入指标体系基本表错误。");
		}
		insertDetail(buildTreeVO);
		return ResponseUtil.getResponseString(ErrorCode.SUCCESSFUL, "插入成功", "");
	}

	private String insertDetail(BuildTreeVO buildTreeVO) {
		String indicatorName = buildTreeVO.getName();
		Date createTime = new Date();
		Integer userId = buildTreeVO.getUserId();
		int prIndicatorSystemId = buildTreeVO.getIndicatorSystemId();
		List<ListEntity> list = buildTreeVO.getList();
		IndicatorBasePO indicatorBasePO = indicatorSystemMapper.getIndicatorInfoByName(indicatorName);
		int nowIndicatorSystemId = indicatorBasePO.getId();
		// 插入一级根结点
		try {
			indicatorSystemMapper.insertIndicatorBaseDetail(nowIndicatorSystemId, indicatorName, indicatorName,
					IndicatorDetailPO.ROOT_LEVEL, IndicatorDetailPO.ROOT_WEIGHT, null, null, null);
		} catch (Exception e) {
			throw new GlobalException("写入数据库错误，请联系系统管理员");
		}

		for (int i = 0; i < list.size(); i++) {
			ListEntity listEntity = list.get(i);
			insertAboutList(indicatorName, listEntity.getIndicatorName(), prIndicatorSystemId, nowIndicatorSystemId);
		}

		initRelativeWeight(nowIndicatorSystemId);
		return ResponseUtil.getResponseString(ErrorCode.SUCCESSFUL, "插入成功", "");
	}

	private void initRelativeWeight(int nowIndicatorSystemId) {
		List<IndicatorDetailPO> rawIndicators = indicatorSystemMapper
				.getOrderdIndicatorDetailByIndicatorId(nowIndicatorSystemId);
		List<IndicatorDetailPO> indicators = rawIndicators;
		List<TreeVO> treeVOS = getTreeList(indicators, nowIndicatorSystemId);
		setOne(treeVOS.get(0));
	}

	private void setOne(TreeVO treeVO) {
		if (treeVO.getChildList() == null) {
			return;
		}
		List<TreeVO> treeVOS = treeVO.getChildList();
		double sum = 0.0;
		for (int i = 0; i < treeVOS.size(); i++) {
			sum += treeVOS.get(i).getRelativeWeight();
		}
		for (TreeVO treeVO2 : treeVOS) {
			indicatorSystemMapper.updateDetailRelativeWeightByES(treeVO2.getId(), treeVO2.getRelativeWeight() / sum);
			setOne(treeVO2);
		}
	}

	/**
	 * 将每一级节点插入到表中
	 * 
	 * @param rootName
	 * @param indicatorName
	 * @param prIndicatorSystemId
	 * @param nowIndicatorSystemId
	 */
	private void insertAboutList(String rootName, String indicatorName, int prIndicatorSystemId,
			int nowIndicatorSystemId) {
		// 查询模板指标的信息
		IndicatorDetailPO indicatorDetailPO = indicatorSystemMapper
				.getIndicatorDetailByIndicatorSystemIdAndIndicatorName(prIndicatorSystemId, indicatorName);
		if (indicatorDetailPO == null) {
			throw new GlobalException("查询原节点id：" + prIndicatorSystemId + "信息有误");
		}
		// 将模板指标的所有祖先节点（根节点除外）找到
		List<IndicatorDetailPO> parents = new ArrayList<>();
		String rawPath = indicatorDetailPO.getIndicatorPath();
		List<String> stringList = DecodePath.decodePath(rawPath);
		for (int i = 1; i < stringList.size(); i++) {
			IndicatorDetailPO indicatorDetailPO1 = indicatorSystemMapper
					.getIndicatorDetailByIndicatorSystemIdAndIndicatorName(prIndicatorSystemId, stringList.get(i));
			parents.add(indicatorDetailPO1);
		}
		StringBuilder nowPath = new StringBuilder(rootName);

		for (int i = 0; i < parents.size(); i++) {
			nowPath.append("/");
			nowPath.append(parents.get(i).getIndicatorName());
			IndicatorDetailPO prototypeDetailPO = indicatorSystemMapper
					.getIndicatorDetailByIndicatorSystemIdAndIndicatorName(prIndicatorSystemId,
							parents.get(i).getIndicatorName());
			IndicatorDetailPO indicatorDetailPO1 = indicatorSystemMapper
					.getIndicatorDetailByIndicatorSystemIdAndIndicatorName(nowIndicatorSystemId,
							parents.get(i).getIndicatorName());
			if (indicatorDetailPO1 != null) {
				continue;
			}
			try {
				indicatorSystemMapper.insertIndicatorBaseDetail(nowIndicatorSystemId, parents.get(i).getIndicatorName(),
						nowPath.toString(), parents.get(i).getIndicatorLevel(), parents.get(i).getRelativeWeight(),
						parents.get(i).getAbsoluteWeight(), parents.get(i).getParamId(), parents.get(i).getRemark());
			} catch (Exception e) {
				throw new GlobalException("插入到明细表错误！");
			}
			// 获取刚刚插入到明细表的指标
			IndicatorDetailPO just = indicatorSystemMapper.getIndicatorDetailByIndicatorSystemIdAndIndicatorName(
					nowIndicatorSystemId, parents.get(i).getIndicatorName());
			// 查看模板该指标是否含有计算方法
			ParamCalPO paramCalPO = indicatorSystemMapper.getParamCalPOByNodeId(parents.get(i).getId());
			// 如果有计算方法，插入到表中，同时把输入参数和预设参数插入到表中
			if (paramCalPO != null) {
				int methodId = paramCalPO.getMethod();
				int nodeId = just.getId();
				try {
					indicatorSystemMapper.insertParamCalPO(nodeId, methodId);
				} catch (Exception e) {
					throw new GlobalException("插入参数计算表错误！");
				}
				// 输入参数复制
				List<InputParamInfo> inputs = indicatorSystemMapper.getInputParamsByNodeId(prototypeDetailPO.getId());
				for (int j = 0; j < inputs.size(); j++) {
					InputParamInfo input = inputs.get(j);
					try {
						indicatorSystemMapper.insertInputParamInfo(just.getId(), input.getParamPrototype(),
								input.getParamName(), input.getParamValue(), input.getParamMaxId(),
								input.getParamMinId(), input.getParamStepId());
					} catch (Exception e) {
						throw new GlobalException("插入输入参数表错误！");
					}
				}
				// 预设参数设置
				List<PresetParamInfo> presets = indicatorSystemMapper
						.getPresetParamsByNodeId(prototypeDetailPO.getId());
				for (int j = 0; j < presets.size(); j++) {
					PresetParamInfo preset = presets.get(j);
					try {
						indicatorSystemMapper.insertPresetParamInfo(just.getId(), preset.getParamPrototype(),
								preset.getParamName(), preset.getParamValue());
					} catch (Exception e) {
						throw new GlobalException("插入预设参数表错误！");
					}
				}
			}

		}

	}

	// 通过string的set构造归一化的权重
	private HashMap<String, Double> buildStringAndRelativeWeightSet(Set<String> strings) {
		HashMap<String, Double> normalized = new LinkedHashMap<>();
		Iterator<String> setIterator = strings.iterator();
		List<Double> doubles = new ArrayList<>();
		while (setIterator.hasNext()) {
			String string = setIterator.next();
			IndicatorDetailPO indicatorDetailPO1 = indicatorSystemMapper.getIndicatorDetailByIndicatorName(string, 1);
			if (indicatorDetailPO1 == null)
				return normalized;
			double relativeWeight = indicatorDetailPO1.getRelativeWeight();
			doubles.add(relativeWeight);
		}
		double sum = 0;
		for (int i = 0; i < doubles.size(); i++) {
			sum += doubles.get(i);
		}
		setIterator = strings.iterator();
		int i = 0;
		while (setIterator.hasNext()) {
			normalized.put(setIterator.next(), doubles.get(i) / sum);
			i++;
		}
		return normalized;
	}

	public String getStepVOByIndicatorId(int indicatorId) {
		List<IndicatorDetailPO> indicatorDetailPOS = indicatorSystemMapper
				.getOrderdIndicatorDetailByIndicatorId(indicatorId);
		List<IndicatorDetailPO> noParamsDetailPOS = indicatorDetailPOS;
		if (indicatorDetailPOS.size() <= 0) {
			return ResponseUtil.getResponseString(ErrorCode.ERROR, "查询指标体系错误，请联系系统管理员", "");
		}
		StepVO stepVO = new StepVO();
		List<String> listRoot = getListRootByIndicatorId(indicatorId, noParamsDetailPOS);
		stepVO.setListRoot(listRoot);
		stepVO.setStepCount(listRoot.size());
		List<List<SliderVO>> sliderVOS = getSliderVOSByIndicatorId(indicatorId, listRoot);
		stepVO.setSliderVOS(sliderVOS);
		List<double[][]> expertScores = getExpertScoresBySliderVOS(sliderVOS);
		stepVO.setExpertScores(expertScores);
		return ResponseUtil.getResponseString(ErrorCode.SUCCESSFUL, "查询成功", stepVO);
	}

	private List<double[][]> getExpertScoresBySliderVOS(List<List<SliderVO>> sliderVOS) {
		List<double[][]> expertScores = new ArrayList<>();
		for (int i = 0; i < sliderVOS.size(); i++) {
			List<SliderVO> sliderVOS1 = sliderVOS.get(i);
			int size = sliderVOS1.size();
			double[][] expertScore = new double[size][size];
			for (int j = 0; j < size; j++) {
				for (int k = 0; k < size; k++) {
					expertScore[j][k] = 1.0;
				}
			}
			expertScores.add(expertScore);
		}
		return expertScores;
	}

	private List<List<SliderVO>> getSliderVOSByIndicatorId(int indicatorId, List<String> listRoot) {
		List<List<SliderVO>> lists = new ArrayList<>();
		for (int i = 0; i < listRoot.size(); i++) {
			List<SliderVO> sliderVOS = new ArrayList<>();
			String indicatorName = listRoot.get(i);
			IndicatorDetailPO indicatorDetailPO = indicatorSystemMapper
					.getIndicatorDetailByIndicatorSystemIdAndIndicatorName(indicatorId, indicatorName);
			if (indicatorDetailPO == null)
				return lists;
			int level = indicatorDetailPO.getIndicatorLevel() + 1;
			List<IndicatorDetailPO> indicatorDetailPOS = indicatorSystemMapper
					.getIndicatorDetailByIndicatorLevelAndIndicatorNameLike(level, indicatorName, indicatorId);
			for (int j = 0; j < indicatorDetailPOS.size(); j++) {
				if (!indicatorDetailPathHas(indicatorDetailPOS.get(j), indicatorName)) {
					indicatorDetailPOS.remove(j);
					j--;
				}
			}
			for (int j = 0; j < indicatorDetailPOS.size(); j++) {
				SliderVO sliderVO = new SliderVO();
				sliderVO.setId(indicatorDetailPOS.get(j).getId());
				sliderVO.setName(indicatorDetailPOS.get(j).getIndicatorName());
				sliderVO.setValue(0);
				sliderVOS.add(sliderVO);
			}
			lists.add(sliderVOS);
		}
		return lists;
	}

	private List<String> getListRootByIndicatorId(int indicatorId, List<IndicatorDetailPO> indicatorDetailPOS) {
		List<String> list = new ArrayList<>();
		int level = indicatorDetailPOS.get(indicatorDetailPOS.size() - 1).getIndicatorLevel() - 1;
		for (int i = 0; i < indicatorDetailPOS.size(); i++) {
			if (indicatorDetailPOS.get(i).getIndicatorLevel() > level
					|| indicatorDetailPOS.get(i).getParamId() != null) {
				indicatorDetailPOS.remove(i);
				i--;
			}
		}
		List<TreeVO> treeVOS = getTreeList(indicatorDetailPOS, indicatorId);
		Queue<TreeVO> treeVOQueue = new LinkedList<>();
		treeVOQueue.add(treeVOS.get(0));
		while (treeVOQueue.size() > 0) {
			TreeVO treeVO = treeVOQueue.poll();
			list.add(treeVO.getIndicatorName());
			if (treeVO.getChildList() != null) {
				int len = treeVO.getChildList().size();
				List<TreeVO> treeVOS1 = treeVO.getChildList();
				for (int i = 0; i < len; i++) {
					TreeVO treeVO1 = treeVOS1.get(i);
					treeVOQueue.add(treeVO1);
				}
			}
		}
		return list;
	}

	/*
	 * Date:2019/10/27 Author:Ge Chen Description:
	 * 某个指标indicatorDetailPO的指标路径中是否含有path
	 */
	public boolean indicatorDetailPathHas(IndicatorDetailPO indicatorDetailPO, String path) {
		List<String> strings = DecodePath.decodePath(indicatorDetailPO.getIndicatorPath());
		for (int i = 0; i < strings.size(); i++) {
			if (strings.get(i).equals(path))
				return true;
		}
		return false;
	}

	public String writeInScore(MatrixBuildVO matrixBuildVO) {
		String expertName = matrixBuildVO.getExpertName();
		Integer indicatorId = matrixBuildVO.getIndicatorId();
		List<ExpertScorePO> expertScorePOList = indicatorSystemMapper
				.getExpertScoreByExpertNameAndIndicatorId(expertName, indicatorId);
		if (expertScorePOList.size() != 0)
			return ResponseUtil.getResponseString(ErrorCode.ERROR, "您已经对该指标体系打过分数", "");
		StepVO stepVO = matrixBuildVO.getStepVO();
		List<String> names = stepVO.getListRoot();
		// copy indicatorItems form table detail and set columns except judgment_matrix
		// & weight
		copyIndicatorItems(indicatorId, expertName);
		// get judgment_matrix and set
		List<List<SliderVO>> lists = stepVO.getSliderVOS();
		for (int i = 0; i < names.size(); i++) {
			ExpertScorePO expertScorePO = indicatorSystemMapper.getExpertScoreByIndicatorIdAndName(indicatorId,
					names.get(i), expertName);
			if (expertScorePO == null)
				return ResponseUtil.getResponseString(ErrorCode.ERROR, "查询错误，请联系系统管理员", "");
			Double matrix[][] = getMatrixByExpertScores(stepVO.getExpertScores().get(i));
			String judgmentMatrix = getMatrixStringByDouble(matrix);
			indicatorSystemMapper.updateJudgmentMatrixById(expertScorePO.getId(), judgmentMatrix);
		}
		// calculate weight and set
		calculateWeightAndSet(expertName, indicatorId);
		// set Root weight
		setRootWeight(expertName, indicatorId);
		// maybe should update Table detail weight
		updateTableDetail(expertName, indicatorId);
		return "success";
	}

	private void setRootWeight(String expertName, Integer indicatorId) {
		List<ExpertScorePO> expertScorePOS = indicatorSystemMapper.getExpertScoreByExpertNameAndIndicatorId(expertName,
				indicatorId);
		ExpertScorePO expertScorePO = expertScorePOS.get(0);
		indicatorSystemMapper.updateRelativeWeightByPrimaryId(expertScorePO.getId(), 1.0);
	}

	private Double[][] getMatrixByExpertScores(double[][] doubles) {
		Double[][] matrix = new Double[doubles.length][doubles.length];
		for (int i = 0; i < doubles.length; i++) {
			for (int j = 0; j < doubles.length; j++) {
				if (i == j) {
					matrix[i][j] = 1.0;
				} else {
					matrix[i][j] = doubles[i][j];
				}
			}
		}
		return matrix;
	}

	private void updateTableDetail(String expertName, Integer indicatorId) {
		// 针对单个专家打分表的更新
		// TODO: 2019/8/18 将来可能会结合多个专家的打分表
		List<ExpertScorePO> expertScorePOS = indicatorSystemMapper.getExpertScoreByExpertNameAndIndicatorId(expertName,
				indicatorId);
		if (expertScorePOS == null)
			return;
		for (int i = 0; i < expertScorePOS.size(); i++) {
			ExpertScorePO expertScorePO = expertScorePOS.get(i);
			IndicatorDetailPO indicatorDetailPO = indicatorSystemMapper.getIndicatorDetailByIndicatorName(
					expertScorePO.getIndicatorName(), expertScorePO.getIndicatorSystemId());
			indicatorSystemMapper.updateDetailRelativeWeightByES(indicatorDetailPO.getId(),
					expertScorePO.getRelativeWeight());
		}
	}

	private void calculateWeightAndSet(String expertName, Integer indicatorId) {
		AHP ahp = new AHP();
		// calculate second and set
		Queue<ExpertScorePO> expertScorePOQueue = new LinkedList<>();
		List<ExpertScorePO> expertScorePOS = indicatorSystemMapper.getExpertScoreByExpertNameAndIndicatorId(expertName,
				indicatorId);
		for (int i = 0; i < expertScorePOS.size(); i++) {
			ExpertScorePO expertScorePO = expertScorePOS.get(i);
			if (expertScorePO.getJudgmentMatrix() != null) {
				expertScorePOQueue.add(expertScorePO);
			}
		}
		while (expertScorePOQueue.size() > 0) {
			ExpertScorePO expertScorePO = expertScorePOQueue.poll();
			String matrix = expertScorePO.getJudgmentMatrix();
			double[][] nextWeights = DecodeMatrix.DecodeMatrix(matrix);
			double[] result;
			result = ahp.getVectorByMatrix(nextWeights, 0.1);
			Queue<Double> queue = new LinkedList<>();
			for (int i = 0; i < result.length; i++) {
				double temp = get45De4(result[i]);
				queue.add(temp);
			}
			List<String> strings = DecodePath.decodePath(expertScorePO.getIndicatorPath());
			int level = strings.size();
			List<ExpertScorePO> expertScorePOS1 = indicatorSystemMapper.getChildNodeByName(indicatorId, expertName,
					expertScorePO.getIndicatorName());
			for (int i = 0; i < expertScorePOS1.size(); i++) {
				ExpertScorePO expertScorePO1 = expertScorePOS1.get(i);
				List<String> strings1 = DecodePath.decodePath(expertScorePO1.getIndicatorPath());
				if (strings1.size() != (level + 1)) {
					expertScorePOS1.remove(i);
					i--;
				}
			}
			for (int i = 0; i < expertScorePOS1.size(); i++) {
				ExpertScorePO expertScorePO1 = expertScorePOS1.get(i);
				double relativeWeight = queue.poll();
				indicatorSystemMapper.updateRelativeWeightByPrimaryId(expertScorePO1.getId(), relativeWeight);
			}
		}
	}

	private String getMatrixStringByDouble(Double[][] matrix) {
		return EncodeMatrix.EncodeMatrix(matrix, matrix.length);
	}

	private Double[][] getMatrixBySliderVOList(List<SliderVO> sliderVOS) {
		if (sliderVOS.size() <= 0)
			return null;
		else if (sliderVOS.size() == 1) {
			Double[][] a = { { 1.0 } };
			return a;
		} else {
			int length = sliderVOS.size();
			Double[][] matrix = new Double[length][length];
			for (int i = 0; i < length; i++) {
				for (int j = 0; j < length; j++) {
					matrix[i][j] = getDouble(i, j, sliderVOS);
				}
			}
			return matrix;
		}
	}

	private Double getDouble(int i, int j, List<SliderVO> sliderVOS) {
		if (i == j)
			return 1.0;
		SliderVO sliderVO1 = sliderVOS.get(i);
		SliderVO sliderVO2 = sliderVOS.get(j);
		int vo1 = sliderVO1.getValue();
		int vo2 = sliderVO2.getValue();
		double delta = (vo1 - vo2) / 10;
		if (delta < 0) {
			return 1 / (-delta);
		} else if (delta < 1e-8) {
			return 1.0;
		} else
			return delta;
	}

	private void copyIndicatorItems(Integer indicatorId, String expertName) {
		List<IndicatorDetailPO> rawIndicatorDetailPOS = indicatorSystemMapper
				.getDoubleOrderdIndicatorDetailByIndicatorId(indicatorId);
		List<IndicatorDetailPO> indicatorDetailPOS = rawIndicatorDetailPOS;
		if (indicatorDetailPOS.size() <= 0)
			return;
		for (int i = 0; i < indicatorDetailPOS.size(); i++) {
			IndicatorDetailPO indicatorDetailPO = indicatorDetailPOS.get(i);
			Integer indicatorSystemId = indicatorDetailPO.getIndicatorSystemId();
			String indicatorName = indicatorDetailPO.getIndicatorName();
			String indicatorPath = indicatorDetailPO.getIndicatorPath();
			indicatorSystemMapper.insertExpertScore(indicatorSystemId, indicatorName, indicatorPath, null, null, null,
					expertName);
		}
	}

//    //将指标体系中的参数项删除
//    private List<IndicatorDetailPO> getNoParamsListByDetailPOS(List<IndicatorDetailPO> indicatorDetailPOS) {
//        Queue<Integer> queue = new PriorityQueue<>();
//        for (int i = 0; i < indicatorDetailPOS.size(); i++) {
//        	IndicatorDetailPO indicatorDetailPO = indicatorDetailPOS.get(i);
//        	if(indicatorDetailPO.getParamId()!=null){
//        		queue.offer(indicatorDetailPO.getId());
//        	}
//        }
//        List<TreeVO> treeVOS = new ArrayList<>();
//        try {
//        	treeVOS = getTreeVOListWithoutParentByDetailList(indicatorDetailPOS);
//		} catch (Exception e) {
//			e.printStackTrace();
//			return null;
//		}
//        while (queue.size() > 0) {
//            Integer integer = queue.poll();
//            for (int i = 0; i < treeVOS.size(); i++) {
//                if (integer.equals(treeVOS.get(i).getParentId())) {
//                    int id = treeVOS.get(i).getId();
//                    for (int j = 0; j < indicatorDetailPOS.size(); j++) {
//                        if (indicatorDetailPOS.get(j).getId() == id) {
//                            indicatorDetailPOS.remove(j);
//                            break;
//                        }
//                    }
//                }
//            }
//        }
//        return indicatorDetailPOS;
//    }

	private List<TreeVO> getTreeVOListWithoutParentByDetailList(List<IndicatorDetailPO> newEntityList)
			throws Exception {
		List<TreeVO> oldTree = new ArrayList<>();
		int indicatorId = newEntityList.get(0).getIndicatorSystemId();
		for (int i = 0; i < newEntityList.size(); i++) {
			TreeVO treeVO = new TreeVO();
			treeVO.setIndicatorName(newEntityList.get(i).getIndicatorName());
			treeVO.setAbsoluteWeight(newEntityList.get(i).getAbsoluteWeight());
			treeVO.setRelativeWeight(newEntityList.get(i).getRelativeWeight());
			treeVO.setId(newEntityList.get(i).getId());
			String path = newEntityList.get(i).getIndicatorPath();
			List<String> paths = DecodePath.decodePath(path);
			if (i != 0) {
				int index = 0;
				for (int g = 0; g < paths.size(); g++) {
					if (paths.get(g).equals(newEntityList.get(i).getIndicatorName())) {
						index = g - 1;
					}
				}
				try {
					IndicatorDetailPO parent = indicatorSystemMapper.getIndicatorDetailByIndicatorName(paths.get(index),
							indicatorId);
					treeVO.setParentId(parent.getId());
				} catch (Exception e) {
					throw new DbException("指标体系id:" + indicatorId + " 中的 " + newEntityList.get(i).getIndicatorName()
							+ " 的父节点没有录入，请仔细检查");
				}
			} else
				treeVO.setParentId(-1);
			oldTree.add(treeVO);
		}
		return oldTree;
	}

	public String getPieChartByIndicatorSystemId(int indicatorSystemId) {
		List<PieVO> pieVOS = new ArrayList<>();
		List<IndicatorDetailPO> indicatorDetailPOS = indicatorSystemMapper
				.getIndicatorDetailByIndicatorSystemIdAndIndicatorLevel(indicatorSystemId, 2);
		if (indicatorDetailPOS == null || indicatorDetailPOS.size() < 0) {
			return ResponseUtil.getResponseString(ErrorCode.ERROR, "查询失败", "");
		}
		for (IndicatorDetailPO indicatorDetailPO : indicatorDetailPOS) {
			PieVO pieVO = new PieVO();
			pieVO.setName(indicatorDetailPO.getIndicatorName());
			pieVO.setValue(indicatorDetailPO.getRelativeWeight());
			pieVOS.add(pieVO);
		}
		return ResponseUtil.getResponseString(ErrorCode.SUCCESSFUL, "查询成功", pieVOS);
	}

	public String getPieChartByPieNeedVO(PieNeedVO pieNeedVO) {
		if (pieNeedVO == null) {
			return ResponseUtil.getResponseString(ErrorCode.ERROR, "查询失败", "");
		}
		int indicatorSystemId = pieNeedVO.getIndicatorSystemId();
		String indicatorName = pieNeedVO.getIndicatorName();
		IndicatorDetailPO indicatorDetailPO = indicatorSystemMapper
				.getIndicatorDetailByIndicatorSystemIdAndIndicatorName(indicatorSystemId, indicatorName);
		if (indicatorDetailPO == null) {
			return ResponseUtil.getResponseString(ErrorCode.ERROR, "查询失败", "");
		}
		int indicatorLevel = indicatorDetailPO.getIndicatorLevel();
		List<IndicatorDetailPO> next = indicatorSystemMapper
				.getIndicatorDetailByIndicatorSystemIdAndIndicatorLevel(indicatorSystemId, indicatorLevel + 1);
		if (next.size() == 0) {
			return ResponseUtil.getResponseString(ErrorCode.ERROR, "该指标无下级结点", "");
		}
		for (int i = 0; i < next.size(); i++) {
			IndicatorDetailPO indicatorDetailPO1 = next.get(i);
			if (!indicatorDetailPathHas(indicatorDetailPO1, indicatorName)) {
				next.remove(i);
				i--;
			}
		}

		List<PieVO> pieVOS = new ArrayList<>();
		for (IndicatorDetailPO indicatorDetailPO1 : next) {
			PieVO pieVO = new PieVO();
			pieVO.setName(indicatorDetailPO1.getIndicatorName());
			pieVO.setValue(indicatorDetailPO1.getRelativeWeight());
			pieVOS.add(pieVO);
		}
		return ResponseUtil.getResponseString(ErrorCode.SUCCESSFUL, "查询成功", pieVOS);
	}

	public String getIndicatorEdit(Integer indicatorSystemId) {
		List<IndicatorDetailPO> indicatorDetailPOS = indicatorSystemMapper
				.getOrderdIndicatorDetailByIndicatorId(indicatorSystemId);
		List<IndicatorDetailPO> noParams = indicatorDetailPOS;
		return ResponseUtil.getResponseString(ErrorCode.SUCCESSFUL, "查询成功", noParams);
	}

	public String updateRelativeWeightByList(List<IndicatorDetailPO> indicatorDetailPOS) {
		for (int i = 0; i < indicatorDetailPOS.size(); i++) {
			IndicatorDetailPO indicatorDetailPO = indicatorDetailPOS.get(i);
			try {
				indicatorSystemMapper.updateDetailRelativeWeightByES(indicatorDetailPO.getId(),
						indicatorDetailPO.getRelativeWeight());
			} catch (Exception e) {
				return ResponseUtil.getResponseString(ErrorCode.ERROR, "更新失败", "");
			}
		}
		return ResponseUtil.getResponseString(ErrorCode.SUCCESSFUL, "更新成功", "");
	}

	public String getExpertPOExist(ExpertVO expertVO) {
		String expertName = expertVO.getExpertName();
		String indicatorName = expertVO.getIndicatorName();
		IndicatorBasePO indicatorBase = indicatorSystemMapper.getIndicatorInfoByName(indicatorName);
		if (indicatorBase == null) {
			return ResponseUtil.getResponseString(ErrorCode.ERROR, "未查询到相关指标体系", "");
		}

		List<ExpertScorePO> experts = indicatorSystemMapper.getExpertScoreByExpertNameAndIndicatorId(expertName,
				indicatorBase.getId());
		if (experts.size() >= 1) {
			return ResponseUtil.getResponseString(ErrorCode.ERROR, "已经对该指标体系打过分数", "");
		}
		return ResponseUtil.getResponseString(ErrorCode.SUCCESSFUL, "查询成功", "");
	}

	public String getIndicatorBaseByName(String indicatorName) {
		IndicatorBasePO indicatorBase = indicatorSystemMapper.getIndicatorInfoByName(indicatorName);
		if (indicatorBase == null) {
			return ResponseUtil.getResponseString(ErrorCode.ERROR, "未查询到相关指标体系", "");
		} else {
			return ResponseUtil.getResponseString(ErrorCode.SUCCESSFUL, "", indicatorBase);
		}
	}

	/**
	 * 删除指定的指标体系
	 * 
	 * @param indicatorId
	 * @return
	 */
	public String deleteIndicatorInfosByIndicatorId(int indicatorId) {
		List<IndicatorDetailPO> details = indicatorSystemMapper
				.getDoubleOrderdIndicatorDetailByIndicatorId(indicatorId);
		if (details == null || details.size() == 0) {
			throw new GlobalException("该指标体系下无指标详情数据");
		}
		deleteIndicators(indicatorId, details);
		return ResponseUtil.getResponseString(ErrorCode.SUCCESSFUL, "删除成功", "");
	}

	/**
	 * 根据指标详情先删除计算方法信息及参数信息，然后删除指标信息与指标体系信息
	 * 
	 * @param indicatorId
	 * @param details
	 */
	@Transactional
	private void deleteIndicators(Integer indicatorSystemId, List<IndicatorDetailPO> details) {
		for (int i = 0; i < details.size(); i++) {
			IndicatorDetailPO indicator = details.get(i);
			try {
				indicatorSystemMapper.deleteParamCalItemsByNodeId(indicator.getId());
			} catch (Exception e) {
				throw new GlobalException("删除节点id为：" + indicator.getId() + "的计算方法错误");
			}
			try {
				indicatorSystemMapper.deleteInputParamInfosByNodeId(indicator.getId());
			} catch (Exception e) {
				throw new GlobalException("删除节点id为：" + indicator.getId() + "的输入参数错误");
			}
			try {
				indicatorSystemMapper.deletePresetParamInfosByNodeId(indicator.getId());
			} catch (Exception e) {
				throw new GlobalException("删除节点id为：" + indicator.getId() + "的预设参数错误");
			}
		}
		try {
			indicatorSystemMapper.deleteDetailByIndicatorId(indicatorSystemId);
		} catch (Exception e) {
			throw new GlobalException("删除指标体系id为：" + indicatorSystemId + "时发生错误");
		}
		try {
			indicatorSystemMapper.deleteBaseByIndicatorId(indicatorSystemId);
		} catch (Exception e) {
			throw new GlobalException("删除指标体系BASE时，id为：" + indicatorSystemId + "时发生错误");
		}
	}

	public String getFH() {
		String str = "南部战区75集团军合成第31旅合成3营营部";
		return ResponseUtil.getResponseString(ErrorCode.SUCCESSFUL, "", str);
	}

	// 根据指标的detailId得到编辑项
	@Transactional
	public String getEditVOByIndicatorDetailId(int indicatorDetailId) {
		IndicatorDetailPO indicatorDetailPO = indicatorSystemMapper.getIndicatorDetailPOById(indicatorDetailId);
		EditVO editVO = new EditVO();
		// 设置该节点的指标名称
		editVO.setIndicatorName(indicatorDetailPO.getIndicatorName());
		// 设置该节点的指标权重
		editVO.setRelativeWeight(indicatorDetailPO.getRelativeWeight());
		// 设置该节点目前的计算方法
		int methodId = 0;
		EvalMethodPO evalMethodPO = indicatorSystemMapper.getEvalMethodPOByNodeId(indicatorDetailPO.getId());
		methodId = evalMethodPO == null ? 0 : evalMethodPO.getMethod();
		editVO.setThisMethodId(methodId);
		// 设置该节点所有的参数节点
		List<ParamInfoPO> paramInfoPOs = getParamInfoPOsByMethodIdAndIndciatorDetailId(methodId,
				indicatorDetailPO.getId());
		editVO.setParamInfoPOs(paramInfoPOs);
		// 设置该节点需要展示的所有计算方法，并且将该节点的计算方法设置为第一个
		List<JSFFPO> jsffpos = indicatorSystemMapper.getAllJSFFs();
		if (jsffpos.size() == 0) {
			throw new GlobalException("获取计算方法失败");
		}
		List<CalMethodPO> calMethodPOs = new ArrayList<>();
		List<IndicatorDetailPO> childs = getChildNode(indicatorDetailPO);
		if (childs != null && childs.size() != 0) {
			// 该节点为非根节点，不可以设置计算方法
			calMethodPOs.add(new CalMethodPO(CalMethodPO.NULL_METHOD, "无计算方法", "该节点为非叶节点，不可设置计算方法", "无计算方法"));
			editVO.setCalMethodPOs(calMethodPOs);
		} else {
			// 为了复用代码，将所有的JSFFPO转化为CalMethodPO
			for (int i = 0; i < jsffpos.size(); i++) {
				CalMethodPO calMethodPO = new CalMethodPO();
				calMethodPO.setMethodId(jsffpos.get(i).getMethodId());
				calMethodPO.setConsise(jsffpos.get(i).getMethodBrief());
				calMethodPO.setDoc(jsffpos.get(i).getMethodDoc());
				calMethodPO.setLabel(jsffpos.get(i).getMethodLabel());
				calMethodPOs.add(calMethodPO);
			}
			List<CalMethodPO> newMethods = new ArrayList<CalMethodPO>();
			if (calMethodPOs.size() != 1) {
				for (int i = 0; i < calMethodPOs.size(); i++) {
					if (calMethodPOs.get(i).getMethodId() == methodId) {
						newMethods.add(calMethodPOs.get(i));
						calMethodPOs.remove(i);
						break;
					}
				}
			}
			for (int i = 0; i < calMethodPOs.size(); i++) {
				newMethods.add(calMethodPOs.get(i));
			}
			editVO.setCalMethodPOs(newMethods);
		}
		return ResponseUtil.getResponseString(ErrorCode.SUCCESSFUL, "查询成功", editVO);
	}

	/**
	 * 保存每个指标明细的数据
	 * 
	 * @param saveEditVO
	 * @return
	 */
	@Transactional
	public String saveInfoBySaveEditVO(SaveEditVO saveEditVO) {
		int indicatorSytemId = saveEditVO.getIndicatorSystemId();
		int indicatorDetailId = saveEditVO.getIndicatorDetailId();
		EditVO editVO = saveEditVO.getEditVO();
		// 查询到当前修改的指标节点
		IndicatorDetailPO indicatorDetailPO = indicatorSystemMapper.getIndicatorDetailPOById(indicatorDetailId);
		if (indicatorDetailPO == null) {
			throw new GlobalException("未查询到id为：" + indicatorDetailId + "的相关指标");
		}
		// 修改指标名称
		String oldName = indicatorDetailPO.getIndicatorName();
		String newName = saveEditVO.getEditVO().getIndicatorName();
		// 指标名称没有修改
		if (oldName.equals(newName)) {

		} else {
			// 数据库中已经存在有关名称
			IndicatorDetailPO existDetailPO = indicatorSystemMapper
					.getIndicatorDetailByIndicatorSystemIdAndIndicatorName(indicatorDetailPO.getIndicatorSystemId(),
							newName);
			if (existDetailPO != null) {
				throw new GlobalException("该名称已存在于指标体系中，请重新修改");
			}
			// 该节点是根节点，需要更新基本信息表
			if (indicatorDetailPO.getIndicatorLevel() == IndicatorDetailPO.ROOT_LEVEL) {
				indicatorSystemMapper.updateBaseNameByIndicatorSystemId(indicatorDetailPO.getIndicatorSystemId(),
						newName);
			}
			// 更新指标名称
			try {
				indicatorSystemMapper.updateIndicatorNameByPrimaryId(indicatorDetailPO.getId(), newName);
			} catch (Exception e) {
				throw new GlobalException("更改指标名称错误");
			}
			// 更新该指标体系下与该指标有关的指标路径
			List<IndicatorDetailPO> pathHasDetailPOs = indicatorSystemMapper
					.getIndicatorDetailByIndicatorPathHas(indicatorSytemId, oldName);
			if (pathHasDetailPOs != null || pathHasDetailPOs.size() != 0) {
				for (int i = 0; i < pathHasDetailPOs.size(); i++) {
					IndicatorDetailPO pathDetailPO = pathHasDetailPOs.get(i);
					String oldPath = pathDetailPO.getIndicatorPath();
					List<String> pathStrings = DecodePath.decodePath(oldPath);
					for (int j = 0; j < pathStrings.size(); j++) {
						if (pathStrings.get(j).equals(oldName)) {
							pathStrings.set(j, newName);
						}
					}
					String newPath = EncodePath.EncodePath(pathStrings);
					try {
						indicatorSystemMapper.updateIndicatorPathByPrimaryId(pathDetailPO.getId(), newPath);
					} catch (Exception e) {
						throw new GlobalException("更改指标路径错误");
					}
				}
			}
		}
		// 更新权重信息
		try {
			indicatorSystemMapper.updateDetailRelativeWeightByES(indicatorDetailPO.getId(), editVO.getRelativeWeight());
		} catch (Exception e) {
			throw new GlobalException("更新权重信息失败");
		}
		// 将该节点的父节点查询，然后查询兄弟节点，归一化所有的权重
		IndicatorDetailPO fatherNodeDetailPO = getFatherNode(indicatorDetailPO);
		if (fatherNodeDetailPO != null) {
			List<IndicatorDetailPO> childsDetailPOs = getChildNode(fatherNodeDetailPO);
			if (childsDetailPOs.size() > 1) {
				childsDetailPOs = relativeWeightNormalized(childsDetailPOs);
				for (int i = 0; i < childsDetailPOs.size(); i++) {
					IndicatorDetailPO childItem = childsDetailPOs.get(i);
					try {
						indicatorSystemMapper.updateDetailRelativeWeightByES(childItem.getId(),
								childItem.getRelativeWeight());
					} catch (Exception e) {
						throw new GlobalException("更新权重信息失败");
					}
				}
			}
		}
		// 更新计算方法信息
		List<CalMethodPO> methods = editVO.getCalMethodPOs();
		for (int i = 0; i < methods.size(); i++) {
			CalMethodPO methodPO = methods.get(i);
			try {
				indicatorSystemMapper.updateCalMethodDocByMethodId(methodPO.getMethodId(), methodPO.getDoc());
			} catch (Exception e) {
				throw new GlobalException("更新计算方法信息失败");
			}
		}
		// 更新预设参数信息：预设参数更新参数名称和参数值，输入参数更新参数名称
		List<ParamInfoPO> paramInfoPOs = editVO.getParamInfoPOs();
		for (int i = 0; i < paramInfoPOs.size(); i++) {
			ParamInfoPO paramInfoPO = paramInfoPOs.get(i);
			if (paramInfoPO.getType() == ParamInfoPO.PRESET_PARAM) {
				try {
					indicatorSystemMapper.updatePresetParamsInfo(indicatorDetailId, paramInfoPO.getParamPrototype(),
							paramInfoPO.getParamName(), paramInfoPO.getParamValue());
				} catch (Exception e) {
					throw new GlobalException("更新预设参数信息失败");
				}
			} else if (paramInfoPO.getType() == ParamInfoPO.INPUT_PARAM) {
				try {
					indicatorSystemMapper.updateInputParamsInfo(indicatorDetailId, paramInfoPO.getParamPrototype(),
							paramInfoPO.getParamName());
				} catch (Exception e) {
					throw new GlobalException("更新输入参数信息失败");
				}
			}
		}
		return ResponseUtil.getResponseString(ErrorCode.SUCCESSFUL, "保存信息成功", "");
	}

	public String getParamsByMethodId(int methodId) {
		List<EvalParamPO> evalParamPOs = new ArrayList<EvalParamPO>();
		List<EvalMethodPO> evalMethodPOs = indicatorSystemMapper.getEvalMethodPOsByMethodId(methodId);
		if (evalMethodPOs.size() == 0) {
			evalParamPOs.add(new EvalParamPO(0, 0, "该结点无参数项，无阈值", 0.00));
		} else {
			EvalMethodPO evalMethodPO = evalMethodPOs.get(0);
			int nodeId = evalMethodPO.getNodeId();
			List<EvalParamPO> evalParamPOs2 = indicatorSystemMapper.getEvalParamPOsByNodeId(nodeId);
			if (evalParamPOs2.size() == 0) {
				evalParamPOs.add(new EvalParamPO(0, 0, "该结点无参数项，无阈值", 0.00));
			} else {
				evalParamPOs = evalParamPOs2;
			}
		}
		return ResponseUtil.getResponseString(ErrorCode.SUCCESSFUL, "查询成功", evalParamPOs);
	}

	// 根据一个detail的list返回该List的归一化权重
	public List<IndicatorDetailPO> relativeWeightNormalized(List<IndicatorDetailPO> indicatorDetailPOs) {
		double sum = 0.0;
		int size = indicatorDetailPOs.size();
		double subSum = 0.0;
		for (int i = 0; i < size; i++) {
			sum += indicatorDetailPOs.get(i).getRelativeWeight();
		}
		for (int i = 0; i < size - 1; i++) {
			indicatorDetailPOs.get(i).setRelativeWeight(get45De4(indicatorDetailPOs.get(i).getRelativeWeight() / sum));
			subSum += indicatorDetailPOs.get(i).getRelativeWeight();
		}
		indicatorDetailPOs.get(size - 1).setRelativeWeight(1.0 - subSum);
		return indicatorDetailPOs;
	}

	public IndicatorDetailPO getFatherNode(IndicatorDetailPO indicatorDetailPO) {
		int level = indicatorDetailPO.getIndicatorLevel();
		if (level == 1)
			return null;
		String pathString = indicatorDetailPO.getIndicatorPath();
		List<String> pathStrings = DecodePath.decodePath(pathString);
		String fatherString = pathStrings.get(level - 2);
		int indicatorSystemId = indicatorDetailPO.getIndicatorSystemId();
		IndicatorDetailPO indicatorDetailPO2 = indicatorSystemMapper
				.getIndicatorDetailByIndicatorSystemIdAndIndicatorName(indicatorSystemId, fatherString);
		return indicatorDetailPO2;
	}

	public List<IndicatorDetailPO> getChildNode(IndicatorDetailPO indicatorDetailPO) {
		int level = indicatorDetailPO.getIndicatorLevel();
		int indicatorSystemId = indicatorDetailPO.getIndicatorSystemId();
		String indicatorNameString = indicatorDetailPO.getIndicatorName();
		List<IndicatorDetailPO> indicatorDetailPOs = indicatorSystemMapper
				.getIndicatorDetailByIndicatorSystemIdAndIndicatorLevel(indicatorSystemId, level + 1);
		if (indicatorDetailPOs.size() == 0) {
			return null;
		} else {
			for (int i = 0; i < indicatorDetailPOs.size(); i++) {
				if (!indicatorDetailPathHas(indicatorDetailPOs.get(i), indicatorNameString)) {
					indicatorDetailPOs.remove(i);
					i--;
				}
			}
			return indicatorDetailPOs;
		}
	}

	@Transactional
	public String deleteInfoBySaveEditVO(SaveEditVO saveEditVO) {
		EditVO editVO = saveEditVO.getEditVO();
		int indicatorSystemId = saveEditVO.getIndicatorSystemId();
		String indicatorName = editVO.getIndicatorName();
		int indicatorDetailId = saveEditVO.getIndicatorDetailId();
		IndicatorDetailPO indicatorDetailPO = indicatorSystemMapper.getIndicatorDetailPOById(indicatorDetailId);
		if (indicatorDetailPO == null) {
			throw new GlobalException("删除节点失败，请联系系统管理员！");
		}
		// 如果该节点有参数项，将参数项删除
		try {
			indicatorSystemMapper.deleteInputParamInfosByNodeId(indicatorDetailPO.getId());
		} catch (Exception e) {
			throw new GlobalException("删除该节点的输入参数信息失败，请联系系统管理员！");
		}
		try {
			indicatorSystemMapper.deletePresetParamInfosByNodeId(indicatorDetailPO.getId());
		} catch (Exception e) {
			throw new GlobalException("删除该节点的预设参数信息失败，请联系系统管理员！");
		}
		// 如果该节点有计算方法，将计算方法删除
		try {
			indicatorSystemMapper.deleteParamCalItemsByNodeId(indicatorDetailPO.getId());
		} catch (Exception e) {
			throw new GlobalException("删除该节点的计算方法信息失败，请联系系统管理员！");
		}
		// 删除该节点的detail信息
		try {
			indicatorSystemMapper.deleteIndicatorDetailById(indicatorDetailPO.getId());
		} catch (Exception e) {
			throw new GlobalException("删除该节点详情失败，请联系系统管理员！");
		}
		// 将该结点的兄弟节点权重归一化
		IndicatorDetailPO fatherDetailPO = getFatherNode(indicatorDetailPO);
		if (fatherDetailPO == null) {
			throw new GlobalException("删除该节点失败，该节点为根节点，请直接删除指标体系");
		}
		List<IndicatorDetailPO> childs = getChildNode(fatherDetailPO);
		if (childs == null || childs.size() == 0) {
			int a = 1;// no null pointer
		} else if (childs.size() == 1) {
			try {
				indicatorSystemMapper.updateDetailRelativeWeightByES(childs.get(0).getId(), 1.0);
			} catch (Exception e) {
				throw new GlobalException("归一化兄弟节点权重错误，请联系系统管理员");
			}
		} else if (childs.size() > 1) {
			childs = relativeWeightNormalized(childs);
			for (int i = 0; i < childs.size(); i++) {
				try {
					indicatorSystemMapper.updateDetailRelativeWeightByES(childs.get(i).getId(),
							childs.get(i).getRelativeWeight());
				} catch (Exception e) {
					throw new GlobalException("归一化兄弟节点权重错误，请联系系统管理员");
				}
			}
		}

		return ResponseUtil.getResponseString(ErrorCode.SUCCESSFUL, "删除成功", "");
	}

	/**
	 * 增加新的指标体系
	 * 
	 * @param addIndicatorVO
	 * @return
	 */
	public String insertNewIndicatorSystem(AddIndicatorVO addIndicatorVO) {
		// 新增指标体系
		String userId = userService.getCurUserId();
		if (userId == null) {
			throw new GlobalException("未获取到当前用户信息，请联系管理员");
		}
		int userLevel = addIndicatorVO.getUserLevel();
		Date createTime = new Date(System.currentTimeMillis());
		AddTreeVO addTreeVO = addIndicatorVO.getTree();
		String indicatorsysName = addIndicatorVO.getIndicatorSystemName();
		indicatorSystemMapper.insertIndicatorBase2PO(indicatorsysName, createTime, "", "用户自定义", null, userLevel, null,
				userId, indicatorsysName);
		// 将所有的指标体系插入
		IndicatorBase2PO indicatorBasePO = indicatorSystemMapper.getIndicatorInfoByIndicatorsysName(indicatorsysName);
		if (indicatorBasePO == null) {
			return ResponseUtil.getResponseString(ErrorCode.ERROR, "增加指标体系失败", "");
		}
		int indicatorSystemId = indicatorBasePO.getId();
		try {
			insertAllIndciators(indicatorSystemId, indicatorsysName, addTreeVO);
		} catch (Exception e) {
			return ResponseUtil.getResponseString(ErrorCode.ERROR, "增加指标体系失败", "");
		}
		// 初始化权重
		List<IndicatorDetailPO> lists = indicatorSystemMapper.getIndicatorDetailsByPrimaryKey(indicatorSystemId);
		for (int i = 0; i < lists.size(); i++) {
			IndicatorDetailPO indicatorDetailPO = lists.get(i);
			List<IndicatorDetailPO> childs = getChildNode(indicatorDetailPO);
			if (childs == null || childs.size() == 0) {
				// 将该结点的
				continue;
			}
			childs = relativeWeightNormalized(childs);
			try {
				updateRelativeWeightByList(childs);
			} catch (Exception e) {
				return ResponseUtil.getResponseString(ErrorCode.ERROR, "增加指标体系失败", "");
			}
		}
		// 将所有的
		return ResponseUtil.getResponseString(ErrorCode.SUCCESSFUL, "插入成功", "");
	}

	/**
	 * 将对应的指标体系都插入到明细表中
	 * 
	 * @param indicatorSystemId
	 * @param indicatorsysName
	 * @param addTreeVO
	 */
	@Transactional
	private void insertAllIndciators(int indicatorSystemId, String indicatorsysName, AddTreeVO addTreeVO) {
		// 插入根节点信息
		AddTreeVO rooTreeVO = addTreeVO;
		String indicatorPath = indicatorsysName;
		String indicatorName = indicatorsysName;
		int indicatorLevel = 1;
		double relativeWeight = 1.0;
		try {
			indicatorSystemMapper.insertIndicatorBaseDetail(indicatorSystemId, indicatorName, indicatorPath,
					indicatorLevel, relativeWeight, null, null, "");
		} catch (Exception e) {
			e.printStackTrace();
			throw new GlobalException("插入到基本信息表时错误");
		}

		// 依次插入每一级节点
		Queue<AddTreeVO> treeVOs = new LinkedList<AddTreeVO>();
		Queue<String> pathQueue = new LinkedList<String>();
		List<AddTreeVO> childs = rooTreeVO.getChildren();
		if (childs != null && childs.size() != 0) {
			for (AddTreeVO temp : childs) {
				treeVOs.add(temp);
				pathQueue.add(indicatorPath + "/" + temp.getLabel());
			}
		}
		while (!treeVOs.isEmpty()) {
			AddTreeVO child = treeVOs.poll();
			String childIndicatorPath = pathQueue.poll();
			String childIndicatorName = child.getLabel();
			int childIndicatorLevel = DecodePath.getLevel(childIndicatorPath);
			double childRelativeWeight = 1.0;
			try {
				indicatorSystemMapper.insertIndicatorBaseDetail(indicatorSystemId, childIndicatorName,
						childIndicatorPath, childIndicatorLevel, childRelativeWeight, null, null, "");
			} catch (Exception e) {
				e.printStackTrace();
				throw new GlobalException("插入到指标体系明细信息表时错误");
			}

			List<AddTreeVO> grands = child.getChildren();
			if (grands != null) {
				for (AddTreeVO grand : grands) {
					treeVOs.add(grand);
					pathQueue.add(childIndicatorPath + "/" + grand.getLabel());
				}
			}
		}

	}

	public String test(int i) {
		if (i == 0) {
			throw new GlobalException("测试数据异常");
		} else {
			return "success";
		}
	}

	@Transactional
	private List<ParamInfoPO> getParamInfoPOsByMethodIdAndIndciatorDetailId(int methodId, int indicatorDetailId) {
		List<ParamInfoPO> paramInfoPOs = new ArrayList<>();
		if (methodId == JSFFPO.NULL_METHOD) {
			paramInfoPOs.add(new ParamInfoPO("无参数模板", "无参数名称", 0.0, ParamInfoPO.NO_PARAM));
		} else {
			// 获取该方法对应的参数模板
			List<ParamPrototype> paramPrototypes = indicatorSystemMapper.getParamPrototypesByMethodId(methodId);
			if (paramPrototypes.size() == 0) {
				throw new GlobalException("该方法没有录入参数模板");
			}
			for (int i = 0; i < paramPrototypes.size(); i++) {
				ParamPrototype prototype = paramPrototypes.get(i);
				if (prototype.getType() == ParamPrototype.INPUT_PARAM) {
					InputParamInfo inputParam = indicatorSystemMapper
							.getInputParamsByNodeIdAndParamPrototype(indicatorDetailId, prototype.getParamPrototype());
					if (inputParam == null) {
						throw new GlobalException("根据输入参数模板" + prototype.getParamPrototype() + "和节点id:"
								+ indicatorDetailId + "，未找到对应的输入参数信息");
					}
					paramInfoPOs.add(new ParamInfoPO(inputParam.getParamPrototype(), inputParam.getParamName(),
							inputParam.getParamValue(), ParamInfoPO.INPUT_PARAM));
				} else if (prototype.getType() == ParamPrototype.PRESET_PARAM) {
					PresetParamInfo presetParam = indicatorSystemMapper
							.getPresetParamsByNodeIdAndParamPrototype(indicatorDetailId, prototype.getParamPrototype());
					if (presetParam == null) {
						throw new GlobalException("根据预设输入参数模板" + prototype.getParamPrototype() + "和节点id:"
								+ indicatorDetailId + "，未找到对应的预设参数信息");
					}
					paramInfoPOs.add(new ParamInfoPO(presetParam.getParamPrototype(), presetParam.getParamName(),
							presetParam.getParamValue(), ParamInfoPO.PRESET_PARAM));
				}
			}
		}
		return paramInfoPOs;
	}

	/**
	 * 根据新的编辑项更改该节点的计算方法
	 * 
	 * @param editVO
	 * @return
	 */
	public String changeMethod(SaveEditVO saveEditVO) {
		int indicatorSystemId = saveEditVO.getIndicatorSystemId();
		EditVO editVO = saveEditVO.getEditVO();
		int indicatorDetailId = saveEditVO.getIndicatorDetailId();
		IndicatorDetailPO indicatorDetailPO = indicatorSystemMapper.getIndicatorDetailPOById(indicatorDetailId);
		if (indicatorDetailPO == null) {
			throw new GlobalException(
					"暂未找到指标体系id为：" + indicatorSystemId + "，指标名称为：" + saveEditVO.getEditVO().getIndicatorName() + "的指标");
		}
		int newMethodId = editVO.getThisMethodId();
		EvalMethodPO evalMethodPO = indicatorSystemMapper.getEvalMethodPOByNodeId(indicatorDetailPO.getId());
		if (evalMethodPO == null) {
			// 该节点为新节点
			// 新增该节点为新的计算方法
			try {
				indicatorSystemMapper.insertParamCalPO(indicatorDetailPO.getId(), newMethodId);
			} catch (Exception e) {
				throw new GlobalException("新增新的计算方法失败，请联系系统管理员！");
			}
			// 根据节点的名称与参数模板增加新的参数信息
			List<ParamPrototype> paramPrototypes = indicatorSystemMapper.getParamPrototypesByMethodId(newMethodId);
			if (paramPrototypes == null) {
				throw new GlobalException("查询计算方法的参数模型错误，请联系系统管理员！");
			}
			insertParamsByIndicatorNameAndParamPrototypes(indicatorDetailPO, paramPrototypes);
		} else {
			// 该节点为修改节点
			// 得到该节点旧的计算方法
			int oldMethodId = evalMethodPO.getMethod();
			if (oldMethodId == newMethodId) {
				throw new GlobalException("修改的计算方法与原计算方法相同，请仔细检查！");
			}
			// 修改该节点为新的计算方法
			try {
				indicatorSystemMapper.updateEvalMethodPOByMethodId(indicatorDetailPO.getId(), newMethodId);
			} catch (Exception e) {
				throw new GlobalException("更新为新的计算方法错误，请联系系统管理员！");
			}
			// 删除该节点旧的输入参数信息
			try {
				indicatorSystemMapper.deleteInputParamInfosByNodeId(indicatorDetailPO.getId());
			} catch (Exception e) {
				throw new GlobalException("删除旧的输入参数信息错误，请联系系统管理员！");
			}
			// 删除该节点旧的预设参数信息
			try {
				indicatorSystemMapper.deletePresetParamInfosByNodeId(indicatorDetailPO.getId());
			} catch (Exception e) {
				throw new GlobalException("删除旧的预设参数信息错误，请联系系统管理员！");
			}
			// 根据节点的名称与参数模板增加新的参数信息
			List<ParamPrototype> paramPrototypes = indicatorSystemMapper.getParamPrototypesByMethodId(newMethodId);
			insertParamsByIndicatorNameAndParamPrototypes(indicatorDetailPO, paramPrototypes);
		}
		return ResponseUtil.getResponseString(ErrorCode.SUCCESSFUL, "更改计算方法成功", "");
	}

	/**
	 * 根据节点的详情与参数模板增加新的参数信息
	 * 
	 * @param indicatorDetailPO
	 * @param paramPrototypes
	 */
	private void insertParamsByIndicatorNameAndParamPrototypes(IndicatorDetailPO indicatorDetailPO,
			List<ParamPrototype> paramPrototypes) {
		String indicatorName = indicatorDetailPO.getIndicatorName();
		int indicatorId = indicatorDetailPO.getId();
		String paramMaxPrototype = getAddInfosByParamPrototype(paramPrototypes);
		if (paramMaxPrototype == null) {
			throw new GlobalException("未找到节点id" + indicatorDetailPO.getId() + "中滑动框最大值所对应的参数，请联系系统管理员！");
		}
		int paramMaxId = 0;
		/**
		 * 修改逻辑，先将预设参数信息录入，然后再根据预设参数录入输入参数信息。原因：增加了param_max_id等查询信息，当新增输入参数信息然后用来查询预设参数id时，要确保预设参数已经插入到表中
		 */
		for (int i = 0; i < paramPrototypes.size(); i++) {
			ParamPrototype paramPrototype = paramPrototypes.get(i);
			if (paramPrototype.getType() == ParamPrototype.INPUT_PARAM) {
				continue;
			} else if (paramPrototype.getType() == ParamPrototype.PRESET_PARAM) {
				try {
					indicatorSystemMapper.insertPresetParamInfo(indicatorId, paramPrototype.getParamPrototype(),
							indicatorName + paramPrototype.getParamPrototype(), 0.00);
				} catch (Exception e) {
					throw new GlobalException(
							"插入" + indicatorName + "指标的预设参数原型" + paramPrototype.getParamPrototype() + "错误，请联系系统管理员！");
				}
			}
		}
		/**
		 * 根据预设参数信息，查找对应的param_max_id
		 */
		PresetParamInfo maxParamInfo = indicatorSystemMapper.getPresetParamsByNodeIdAndParamPrototype(indicatorId,
				paramMaxPrototype);
		if (maxParamInfo == null) {
			throw new GlobalException("未获取到指标id：" + indicatorId + "中的参数原型为：" + paramMaxPrototype + "的预设参数信息。");
		}
		paramMaxId = maxParamInfo.getId();
		for (int i = 0; i < paramPrototypes.size(); i++) {
			ParamPrototype paramPrototype = paramPrototypes.get(i);
			if (paramPrototype.getType() == ParamPrototype.PRESET_PARAM) {
				continue;
			} else if (paramPrototype.getType() == ParamPrototype.INPUT_PARAM) {
				try {
					indicatorSystemMapper.insertInputParamInfo(indicatorId, paramPrototype.getParamPrototype(),
							indicatorName + paramPrototype.getParamPrototype(), 1.00, paramMaxId, 0, 0);
				} catch (Exception e) {
					throw new GlobalException(
							"插入" + indicatorName + "指标的输入参数原型" + paramPrototype.getParamPrototype() + "错误，请联系系统管理员！");
				}
			}
		}
	}

	/**
	 * 在指定指标下增加指标
	 * 
	 * @param indicatorDetailId
	 * @return
	 */
	@Transactional
	public String addIndicator(int indicatorDetailId) {
		// 增加一条新的指标体系
		IndicatorDetailPO indicatorDetailPO = indicatorSystemMapper.getIndicatorDetailPOById(indicatorDetailId);
		if (indicatorDetailPO == null) {
			throw new GlobalException("增加失败，未查询到相关指标");
		}
		try {
			indicatorSystemMapper.insertIndicatorBaseDetail(indicatorDetailPO.getIndicatorSystemId(), "新增指标",
					indicatorDetailPO.getIndicatorPath() + "/" + "新增指标", indicatorDetailPO.getIndicatorLevel() + 1, 1.0,
					null, null, null);
		} catch (Exception e) {
			throw new GlobalException("插入新指标失败，请联系系统管理员！");
		}
		// 将该节点的所有参数信息删除
		try {
			indicatorSystemMapper.deleteInputParamInfosByNodeId(indicatorDetailPO.getId());
		} catch (Exception e) {
			throw new GlobalException("删除输入参数节点失败，请联系系统管理员！");
		}
		try {
			indicatorSystemMapper.deletePresetParamInfosByNodeId(indicatorDetailPO.getId());
		} catch (Exception e) {
			throw new GlobalException("删除预设参数节点失败，请联系系统管理员！");
		}
		// 将该节点的所有子节点权重归一化
		List<IndicatorDetailPO> childs = getChildNode(indicatorDetailPO);
		if (childs != null && childs.size() != 0) {
			childs = relativeWeightNormalized(childs);
			for (int i = 0; i < childs.size(); i++) {
				try {
					indicatorSystemMapper.updateDetailRelativeWeightByES(childs.get(i).getId(),
							childs.get(i).getRelativeWeight());
				} catch (Exception e) {
					throw new GlobalException("更新权重信息失败，请联系系统管理员！");
				}
			}
		}
		return ResponseUtil.getResponseString(ErrorCode.SUCCESSFUL, "新增指标成功", "");
	}

	/**
	 * 根据参数原型返回输入参数的max、min、step映射的参数原型（现在的逻辑只有max）。前提是所需的预设参数信息已经输入
	 * 
	 * @param paramPrototypes
	 * @return 输入参数映射max对应的参数原型
	 */
	public String getAddInfosByParamPrototype(List<ParamPrototype> paramPrototypes) {
		InputParamInfo res = new InputParamInfo();
		for (int i = 0; i < paramPrototypes.size(); i++) {
			ParamPrototype paramPrototype = paramPrototypes.get(i);
			if (paramPrototype.getMapping() != null
					&& paramPrototype.getMapping().equals(ParamPrototype.PARAM_MAX_MAPPING)) {
				return paramPrototype.getParamPrototype();
			}
		}
		return null;
	}
}
